import mx.utils.Delegate;

import gugga.common.EventDescriptor;
import gugga.common.ITask;
import gugga.navigation.NavigationButton;
import gugga.sequence.ExecuteMethodTask;
import gugga.sequence.TaskManager;
import gugga.sequence.TaskSequence;

import useOfSequences.CommonSection;
import gugga.navigation.MenuNavigation;

/**
 * @author bony
 * This section demonstrate four sequences - linear, backward, zigzag and complex.
 * To start some sequence, previous must be completed. 
 */ 
class useOfSequences.DemonstrationSection extends CommonSection 
{
	private var mLinearSequenceButton: NavigationButton;
	private var mBackwardsButton: NavigationButton;
	private var mZigZagSequenceButton: NavigationButton;
	private var mComplexSequenceButton: NavigationButton;	
	
	// Those tasks will be included in appropriate place in all sequences. 
	private var mEnableSequencesNavigationTask: ITask;
	private var mDisableSequencesNavigationTask: ITask;
	private var mUnselectAllSubItemsTask: ITask; 
		
	private var mLinearSequence: TaskSequence;
	private var mBackwardsSequence: TaskSequence;
	private var mZigzagSequence: TaskSequence;
	// ComplexSequence executes complicated, aschyncrons tasks and have to be TaskManager.
	private var mComplexSequence: TaskManager;
	
	public function DemonstrationSection() 
	{
		super();
		
		// Get the instances from the scene.
		// Use "getComponentByPath()" to obtain a reference to the buttons,
		// because their movie clips are nested in the "SequencesNavigation" movie clip 
		// and we can't get to it using getComponent().
		mLinearSequenceButton = getComponentByPath(["SequencesNavigation","btnLinearSequence"]);
		mBackwardsButton = getComponentByPath(["SequencesNavigation","btnBackwards"]);
		mZigZagSequenceButton = getComponentByPath(["SequencesNavigation", "btnZigZagSequence"]);	
		mComplexSequenceButton = getComponentByPath(["SequencesNavigation", "btnComplexSequence"]);		
		
	}
	
	public function initUI()
	{
		super.initUI();
		
		// Configure sequences navigation menu.
		configureButtons();			
		
		// Create task that will disable the menu, until the sequence completes.
		// This task must be included in the beginning of all sequences.
		mDisableSequencesNavigationTask = ExecuteMethodTask.create(this, this.disableButtons);
		// Create task that will enable the menu. This task must be included in the final of all sequences.
		mEnableSequencesNavigationTask = ExecuteMethodTask.create(this, this.enableButtons);
        // Create task that will unselect all the items of the sequences navigation menu.
		// This task must be included in the final of all sequences. This is necessary, because 
		// otherwise the sequences that have been executed stay selected.
		mUnselectAllSubItemsTask = ExecuteMethodTask.create(this, this.unselectButtons);
			
		// Prepare the sequences.	
		
		// Linear sequence is simple sequence that executes the animations one by one.  	
		mLinearSequence = prepareLinearSequence();
		// Backwards sequence is simple sequence that executes the animations backwards.
		mBackwardsSequence = prepareBackwardsSequence();
		// Zigzag sequence is simple sequence that execute the animations in the order :
		// TitleAnim, CupAnim, MailAnim, EggsAnim, LogoAnim.
		mZigzagSequence = prepareZigzagSequence();
		// Complex sequence executes the animations asynchronously. The order is : 
		// TitleAnim, MailAnim starts simultaneously, LogoAnim starts on complete of TitleAnim and MailAnim,
		// CupAnim starts on complete of LogoAnim, CupAnim - on complete of LogoAnim and 
		// EggsAnim in the middle of the CupAnim. 
		mComplexSequence = prepareComplexSequence();
		
		// when button in the navigation is clicked and "navigate" event is dispatched. 
		// This method will trigger execution of the corresponding sequence.
		// Initialization sequence		
		// Using the CommonSection initialization sequence.
		
		// Activating sequence		
		// Using the CommonSection activating sequence.
		
		// Open sequence		
		// Using the CommonSection open sequence.
		
		// Close sequence		
		// Using the CommonSection close sequence.  
	}
	
	private function configureButtons (): Void
	{
		mLinearSequenceButton.addEventListener("click", Delegate.create(this, onLinearSequenceButtonClick));		mBackwardsButton.addEventListener("click", Delegate.create(this, onBackwardsButtonClick));		mZigZagSequenceButton.addEventListener("click", Delegate.create(this, onZigZagSequenceButtonClick));		mComplexSequenceButton.addEventListener("click", Delegate.create(this, onComplexSequenceButtonClick));	}
			
	private function prepareLinearSequence() : TaskSequence
	{
		var linearSequence : TaskSequence = new TaskSequence();
		linearSequence.addTask(mDisableSequencesNavigationTask);
		linearSequence.addTask(mTitleAnim);
		linearSequence.addTask(mMailAnim);
		linearSequence.addTask(mLogoAnim);
		linearSequence.addTask(mCupAnim);
		linearSequence.addTask(mEggsAnim);
		linearSequence.addTask(mEnableSequencesNavigationTask);
		linearSequence.addTask(mUnselectAllSubItemsTask);
	
		return linearSequence;	
	}
	
	private function prepareBackwardsSequence() : TaskSequence
	{
		var backToFrontSequence : TaskSequence = new TaskSequence();
		backToFrontSequence.addTask(mDisableSequencesNavigationTask);
		backToFrontSequence.addTask(mEggsAnim);
		backToFrontSequence.addTask(mCupAnim);
		backToFrontSequence.addTask(mLogoAnim);
		backToFrontSequence.addTask(mMailAnim);
		backToFrontSequence.addTask(mTitleAnim);	
		backToFrontSequence.addTask(mEnableSequencesNavigationTask);
		backToFrontSequence.addTask(mUnselectAllSubItemsTask);	
	
		return backToFrontSequence;	
	}
	
	private function prepareZigzagSequence() : TaskSequence
	{
		var zigzagSequence : TaskSequence = new TaskSequence();
		zigzagSequence.addTask(mDisableSequencesNavigationTask);
		zigzagSequence.addTask(mTitleAnim);
		zigzagSequence.addTask(mCupAnim);
		zigzagSequence.addTask(mMailAnim);
		zigzagSequence.addTask(mEggsAnim);
		zigzagSequence.addTask(mLogoAnim);
		zigzagSequence.addTask(mEnableSequencesNavigationTask);
		zigzagSequence.addTask(mUnselectAllSubItemsTask);		
	
		return zigzagSequence;	
	}
	
	private function prepareComplexSequence() : TaskManager
	{
		// Add cue point at frame 10. When the animation "mCupAnim" reaches to frame 10
		// it will dispatch event "middle".
		mCupAnim.addCuePoint(10, "middle");	
		
		// This is the precondition, which is necessary for the "mEggsAnim" to be executed.
		// The "mEggsAnim" starts when the "mCupAnim" dispatch the event "middle".
		var eggsAnimPrecondition : EventDescriptor = new EventDescriptor(mCupAnim, "middle"); 
		
		// Initialize the Task Manager as unaccepting (false in the constructor), 
		// because don't need to listen for the events, before start.
		// Instantiate task manager. Add all tasks with desired dependencies.
		var mComplexSequenceTaskManager: TaskManager = new TaskManager(false);
		mComplexSequenceTaskManager.addStartingTasks([mDisableSequencesNavigationTask, mTitleAnim, mMailAnim]);
		mComplexSequenceTaskManager.addTaskWithPredecessors(mLogoAnim,[mTitleAnim,mMailAnim]);
		mComplexSequenceTaskManager.addTaskWithPredecessor(mCupAnim, mLogoAnim);
		mComplexSequenceTaskManager.addTaskWithPrecondition(mEggsAnim, eggsAnimPrecondition);
		mComplexSequenceTaskManager.addTaskWithPredecessor(mEnableSequencesNavigationTask, mEggsAnim);
		mComplexSequenceTaskManager.addTaskWithPredecessor(mUnselectAllSubItemsTask, mEnableSequencesNavigationTask);
		mComplexSequenceTaskManager.setFinalTask(mUnselectAllSubItemsTask);
				
		return mComplexSequenceTaskManager;
	}
	
	private function onLinearSequenceButtonClick()
	{			
		mLinearSequence.start();
	}
	
	private function onBackwardsButtonClick()
	{
		mBackwardsSequence.start();
	}
	
	private function onZigZagSequenceButtonClick()
	{
		mZigzagSequence.start();
	}
	
	private function onComplexSequenceButtonClick()
	{
		// Before starting the Task Manger, first must set every task manager item as accepting for all of the 
	    // preconditions that are associated with it.
		mComplexSequence.acceptAll();
		mComplexSequence.start();
	}
	
	private function enableButtons () : Void	 
	{
		mLinearSequenceButton.enable();
		mBackwardsButton.enable();
		mZigZagSequenceButton.enable();
		mComplexSequenceButton.enable();
	}
	
	private function disableButtons () : Void	 
	{
		mLinearSequenceButton.disable();
		mBackwardsButton.disable();
		mZigZagSequenceButton.disable();
		mComplexSequenceButton.disable();
	}
	
	private function unselectButtons () : Void	 
	{
		mLinearSequenceButton.unselect();
		mBackwardsButton.unselect();
		mZigZagSequenceButton.unselect();
		mComplexSequenceButton.unselect();
	}
}	
	
